#pragma once
#include<iostream>
#include<string>
#include<sys/types.h>
#include<sys/stat.h>
#include<unistd.h>
#include<sys/time.h>
#include<atomic>
#include<fstream>
#include<vector>
#include<boost/algorithm/string.hpp>

namespace ns_util
{
   class TimeUtil
   {
   public:
      static std::string GetTimeStamp()
      {
         struct timeval _time;
         gettimeofday(&_time,nullptr);
         return std::to_string(_time.tv_sec);   
      }

      //毫秒级别时间戳
      static std::string GetTimeMs()
      {
         struct timeval _time;
         gettimeofday(&_time,nullptr);
         return std::to_string(_time.tv_sec*1000+_time.tv_usec/1000);
      }
   };
   //增加文件后缀 .cpp .exe .Stderr
   //构建源文件路径+后缀
   const std::string temp_path = "./temp/";
   class PathUtil
   {
   public:
      // test --> ./temp/test.cpp    
      //添加路径后缀
      static std::string AddSuffix(const std::string &file_name, const std::string &suffix)
        {
            std::string path_name = temp_path;
            path_name += file_name;
            path_name += suffix;
            return path_name;
        }

 
      static std::string Src(const std::string & file_name)
      {
         return AddSuffix(file_name,".cpp");
      }
      //构建可执行程序的完整路径+后缀名
       static std::string Exe(const std::string & file_name)
      {
         return  AddSuffix(file_name,".exe");
      }
      //构建标准错误完整的路径+后缀名
       static std::string Stderr(const std::string & file_name)
      {
         return AddSuffix(file_name,".stderr");
      }

      //运行时的临时文件
       static std::string Stdin(const std::string& file_name)
      {
         return AddSuffix(file_name,".stdin");
      }
       static std::string Stdout(const std::string& file_name)
      {
         return AddSuffix(file_name,".stdout");
         
      }   
      //编译时报错
      //编译时的临时文件
      static std::string CompilerError(const std::string & file_name)
      {
         return AddSuffix(file_name,".compiler_error");
      }
   };

   class FileUtil
   {
   public:
      static bool IsFileExists(const std::string& path)
      {
         //int stat(const char *path, struct stat *buf);
         struct stat st;
         if(stat(path.c_str(),&st)==0)
         {
            //获取属性成功,文件已经存在
            return true;
         }
         return false;
      }

      static std::string UniqFileName()
      {
         static std::atomic_uint id(0);
         id++;
         std::string ms=TimeUtil::GetTimeMs();//毫秒级别时间戳
         std::string uniq_id=std::to_string(id);

         return ms+"_"+uniq_id;

      }

      //把content写入target中
      static bool WriteFile(const std::string &target,const std::string &content)
      {
         std::ofstream out(target);
         if(!out.is_open()){
            return false;
         }
         out.write(content.c_str(),content.size());
         out.close();
         return true;
      }

      //想保留\n的话要传keep为true
       static bool ReadFile(const std::string &target,std::string*content,bool keep = false)
      {
         (*content).clear();
         std::ifstream in(target);
         if(!in.is_open())
         {
            return false;
         }
         std::string line;
         while(std::getline(in,line))
         {
            (*content) +=line;
            (*content)+=(keep?"\n":"");
         }
         in.close();
         return true;
      }
   };

   class StringUtil
   {
   public:
   //str切分谁 
   //target保存切割的结果
   //sep分隔符
      static void SplitString(const std::string &str,std::vector<std::string>*target,std::string sep)
      {
         boost::split((*target),str,boost::is_any_of(sep),boost::algorithm::token_compress_on);
      }
   };


}
